﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Workflow.Runtime;
using System.IO;
using System.Xml;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.ComponentModel.Design;
using System.Drawing.Imaging;
using System.Data.SqlClient;
using CommonLibrary.DB;
using Bukovics.Workflow.Hosting;
using System.Workflow.Activities;
using System.Threading;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;
using System.CodeDom;
using CommonLibrary.Common;
using System.Drawing.Design;

namespace ServiceApplication.Service.WorkFlow.WorkflowDesignerApp
{
    public partial class MainForm : Form
    {
        private TypeProvider _typeProvider;
        string XomlFileName = "";
        public MainForm()
        {
            InitializeComponent();
            _typeProvider = new TypeProvider(new ServiceContainer());
            wfDesignCl.TypeProvider = _typeProvider;
        }

        #region 菜单栏

        //新建-新建状态机工作流
        private void menuItem6_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "工作流文件|*.xoml|所有文件|*.*";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.RestoreDirectory = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                XomlFileName = saveFileDialog.FileName;
                IntityWFTempFile(XomlFileName, 2);
                this.wfDesignCl.LoadWorkflow(XomlFileName);
            }
        }
        //新建-新建顺序工作流
        private void menuItem4_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "工作流文件|*.xoml|所有文件|*.*";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.RestoreDirectory = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                XomlFileName = saveFileDialog.FileName;
                IntityWFTempFile(XomlFileName, 1);
                this.wfDesignCl.LoadWorkflow(XomlFileName);
            }
        }

        /// <summary>
        /// 初始化新建的文件
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="wftype">1:顺序工作流 2:状态机工作流</param>
        private void IntityWFTempFile(string filename, int wftype)
        {
            if (!filename.ToLower().EndsWith(".xoml"))
                filename += ".xoml";
            string rulesname = filename.Replace(".xoml", ".rules");
            string layoutname = filename.Replace(".xoml", ".layout");
            FileInfo fi = null;
            if (wftype == 1)
                fi = new FileInfo(@"WFTemplate\顺序工作流.xoml");
            else if (wftype == 2)
                fi = new FileInfo(@"WFTemplate\状态机工作流.xoml");
            if (fi.Exists)
            {
                fi.CopyTo(filename, false);
                fi = new FileInfo(@"WFTemplate\状态机工作流.rules");
                fi.CopyTo(rulesname, false);
                fi = new FileInfo(@"WFTemplate\状态机工作流.layout");
                fi.CopyTo(layoutname, false);
            }
        }
        //打开
        private void OpenMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "xoml files (*.xoml)|*.xoml|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 1;
            openFileDialog.RestoreDirectory = true;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                XomlFileName = openFileDialog.FileName;
                this.wfDesignCl.LoadWorkflow(openFileDialog.FileName);
            }
        }

        //!!开发阶段才能使用保存. 使用阶段只能使用另存为
        private void SaveMenuItem_Click(object sender, EventArgs e)
        {
            //this.wfDesignCl.Save(null);
        }

        #region 菜单栏
        private void saveImageMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Png files (*.Png)|*.Png|All files (*.*)|*.*";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.RestoreDirectory = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
                wfDesignCl.WorkflowView.SaveWorkflowImage(saveFileDialog.FileName, ImageFormat.Png);
        }

        private void SaveAsMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "xoml files (*.xoml)|*.xoml|All files (*.*)|*.*";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.RestoreDirectory = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                XomlFileName = saveFileDialog.FileName;
                this.wfDesignCl.Save(saveFileDialog.FileName);
            }
        }

        private void PageSetupMenuItem_Click(object sender, EventArgs e)
        {
            WorkflowView workflowView = this.wfDesignCl.WorkflowView;
            if (null != workflowView)
            {
                WorkflowPageSetupDialog pageSetupDialog = new WorkflowPageSetupDialog(this.wfDesignCl.WorkflowView as IServiceProvider);
                if (DialogResult.OK == pageSetupDialog.ShowDialog())
                    workflowView.PerformLayout();
            }
        }

        private void PrintPreviewMenuItem_Click(object sender, EventArgs e)
        {
            WorkflowView workflowView = this.wfDesignCl.WorkflowView;
            if (workflowView != null)
            {
                this.wfDesignCl.SuspendLayout();
                workflowView.PrintPreviewMode = !workflowView.PrintPreviewMode;
                PrintPreviewMenuItem.Checked = workflowView.PrintPreviewMode;
                workflowView.ClientSize = this.wfDesignCl.ClientSize;
                this.wfDesignCl.ResumeLayout(true);
            }
        }

        private void PrintMenuItem_Click(object sender, EventArgs e)
        {
            WorkflowView workflowView = this.wfDesignCl.WorkflowView;
            if (null != workflowView)
            {
                PrintDialog printDialog = new System.Windows.Forms.PrintDialog();
                printDialog.AllowPrintToFile = false;
                printDialog.Document = workflowView.PrintDocument;

                try
                {
                    printDialog.ShowDialog();
                }
                catch
                {
                    string errorString = "发生错误，请选择新的打印机";
                    MessageBox.Show(this, errorString, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        private void ExitMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void expandMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Expand);
        }

        private void collapseMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Collapse);
        }

        private void zoom200MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Zoom200Mode);
        }

        private void zoom150MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Zoom200Mode);
        }

        private void zoom100MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Zoom100Mode);
        }

        private void zoom75MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Zoom75Mode);
        }

        private void zoom50MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Zoom50Mode);
        }

        private void zoom10MenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.WorkflowView.Zoom = 10;
        }

        private void zoomShowAllMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.ShowAll);
        }

        private void zoomInNavigationMenuItem_Click(object sender, EventArgs e)
        {
            if (wfDesignCl.WorkflowView == null) return;
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.ZoomIn);
            this.zoomInToolButton.Checked = true;
        }

        private void zoomOutNavigationMenuItem_Click(object sender, EventArgs e)
        {
            if (wfDesignCl.WorkflowView == null) return;
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.ZoomOut);
            this.zoomOut.Checked = true;
        }

        private void panNavigationMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.Pan);
        }

        private void defaultNavigationMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(WorkflowMenuCommands.DefaultFilter);
        }
        #endregion

        #endregion

        #region 工具栏

        private void cutToolStripButton_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(StandardCommands.Cut);
        }

        private void copyToolStripButton_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(StandardCommands.Copy);
        }

        private void pasteToolStripButton_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.InvokeStandardCommand(StandardCommands.Paste);
        }

        private void newSequToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.LoadWorkflow(@"WFTemplate\顺序工作流.xoml");
        }

        private void newStateMenuItem_Click(object sender, EventArgs e)
        {
            this.wfDesignCl.LoadWorkflow(@"WFTemplate\状态机工作流.xoml");
        }

        private bool zoomLevelDirty = false;
        void zoomLevelToolStripButton_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            ParseZoomLevelValue();
        }

        void zoomLevelToolStripButton_Leave(object sender, System.EventArgs e)
        {
            if (this.zoomLevelDirty)
            {
                ParseZoomLevelValue();
                this.zoomLevelDirty = false;
            }
        }

        void zoomLevelToolStripButton_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                ParseZoomLevelValue();
                zoomLevelDirty = false;
                this.wfDesignCl.WorkflowView.Focus();
            }
            else if (e.KeyCode == Keys.Escape)
            {
                //revert the changes back to the zoom level from the workflow
                zoomLevelToolStripButton.Text = this.wfDesignCl.WorkflowView.Zoom + "%";
                zoomLevelDirty = false;
                this.wfDesignCl.WorkflowView.Focus();
            }
            else
            {
                zoomLevelDirty = true;
            }
        }

        void zoomLevelToolStripButton_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Enter && e.KeyCode != Keys.Escape)
            {
                zoomLevelDirty = true;
            }
        }

        private void ParseZoomLevelValue()
        {
            string newZoom = zoomLevelToolStripButton.Text.Trim();
            if (newZoom.EndsWith("%"))
                newZoom = newZoom.Substring(0, newZoom.Length - 1);
            if (newZoom.Length > 0)
            {
                this.wfDesignCl.WorkflowView.Zoom = Convert.ToInt32(newZoom);
            }
        }
        #endregion

        private void MainForm_Load(object sender, EventArgs e)
        {
            //this.wfDesignCl.LoadWorkflow(@"WFTemplate\状态机工作流.xoml");
        }

        private WorkflowInstance createWorkflowFormXomlString(string XomlFileName, Dictionary<string, object> list)
        {
            Guid guid = Guid.NewGuid();
            try
            {
                string xomlString = "";
                string rulesString = "";

                using (System.IO.StreamReader sr = new StreamReader(XomlFileName))
                {
                    xomlString = sr.ReadToEnd();
                }
                if (System.IO.File.Exists(XomlFileName.ToLower().Replace(".xoml", ".rules")))
                {
                    using (System.IO.StreamReader sr = new StreamReader(XomlFileName.ToLower().Replace(".xoml", ".rules")))
                    {
                        rulesString = sr.ReadToEnd();
                    }
                }

                System.Workflow.Runtime.WorkflowInstance instance;
                WorkflowRuntime wfRuntime = new WorkflowRuntime();
                wfRuntime.StartRuntime();

                TextReader xomlText = new StringReader(xomlString);
                XmlReader xoml = XmlReader.Create(xomlText);

                TextReader rulesText = new StringReader(rulesString);
                XmlReader rules = XmlReader.Create(rulesText);

                instance = wfRuntime.CreateWorkflow(xoml, rules, list, guid);
                if (instance != null)
                {
                    instance.Start();
                }
                return instance;

            }
            catch (System.Workflow.ComponentModel.Compiler.WorkflowValidationFailedException ex)
            {
                string errorString = "";
                foreach (ValidationError ve in ex.Errors)
                {
                    errorString = errorString + ve.ErrorText + "\n";
                }

                MessageBox.Show("err:" + errorString);
                return null;
            }
        }

        private bool 编译成功 = false;
        private void menuItem编译_Click(object sender, EventArgs e)
        {
            if (!this.wfDesignCl.Validate())
            {
                //MessageBox.Show("编译失败：请确认每个EventDrivenActivity的Description属性不为空");
                return;
            }
            this.wfDesignCl.Save(null);
            this.wfDesignCl.LoadWorkflow(XomlFileName);  //mlh + 2011-11-17
            Dictionary<string, object> list = new Dictionary<string, object>();

            string rtbXoml = wfDesignCl.loader.XomlFile;

            WorkflowInstance wfInstance = createWorkflowFormXomlString(rtbXoml, list);
            if (wfInstance != null)
            {
                MessageBox.Show("编译成功");
                编译成功 = true;
            }
            else
            {
                MessageBox.Show("编译失败");
            }
        }

        private void menuItem保存到数据库_Click(object sender, EventArgs e)
        {
            if (!编译成功)
            {
                MessageBox.Show("未通过编译，无法存储");
                return;
            }
            if (string.IsNullOrEmpty(Txt_name.Text))
            {
                MessageBox.Show("模板名称未填写！");
                return;
            }

            var path = AppDomain.CurrentDomain.BaseDirectory;
            var file = Directory.GetFiles(path, "imgProc.jpg");
            if (file.Length == 0)
            {
                MessageBox.Show("请先设计好流程图");
            }


            List<SqlParameter> sqlParams = new List<SqlParameter>(){
                new SqlParameter("@wftemplate_name",Txt_name.Text),
                new SqlParameter("@wfdefinition",wfDesignCl.loader.Xoml),
                new SqlParameter("@wfrule",wfDesignCl.loader.Rules),
                new SqlParameter("@wflayout",wfDesignCl.loader.Layout)
            };
            string sql = "insert into wf_template(wftemplate_name,wfdefinition,wfrule,wflayout) values (@wftemplate_name,@wfdefinition,@wfrule,@wflayout)";
            DBExecuteUtil.executeSqlWithPar(sql, sqlParams.ToArray());
            MessageBox.Show("存储成功");
        }

        private void menuItem启动_Click(object sender, EventArgs e)
        {
            #region Data from file
            //XmlReader reader = XmlReader.Create(@"顺序工作流.xoml");
            //XmlReader reader2 = XmlReader.Create(@"顺序工作流.rules");
            #endregion
            #region Data from sql
            //string sql = "select wfmodule_id,wfmodule_name,wfdefinition,wfrule,wflayout from wfmodule where wfmodule_id=9";
            //string[][] result = CommonLibrary.DB.DBExecuteUtil.querySqlArray(sql);
            //TextReader str1 = new StringReader(result[0][2]);
            //TextReader str2 = new StringReader(result[0][3]);
            //XmlReader reader = XmlReader.Create(str1);
            //XmlReader reader2 = XmlReader.Create(str2);
            #endregion
            #region Data from filewrapper
            string sql = "SELECT wftemplate_id,wftemplate_name,wfdefinition,wfrule,wflayout FROM OAonline.dbo.wf_template where wftemplate_id=1";
            string[][] result = CommonLibrary.DB.DBExecuteUtil.querySqlArray(sql);
            TextReader t1 = new StringReader(result[0][2]);
            TextReader t2 = new StringReader(result[0][3]);
            XmlReader reader = XmlReader.Create(t1);
            XmlReader reader2 = XmlReader.Create(t2);
            #endregion
            using (WorkflowRuntimeManager manager
                = new WorkflowRuntimeManager(new WorkflowRuntime()))
            {
                manager.MessageEvent += delegate(
                    Object sender1, WorkflowLogEventArgs e1)
                {
                    Console.WriteLine(e1.Message);
                };
                manager.WorkflowRuntime.StartRuntime();
                manager.StartWorkflow(reader, reader2, null);
                MessageBox.Show("启动成功");
            }
        }

        private void menuItem添加引用_Click(object sender, EventArgs e)
        {
            //AssemblyReferenceForm form
            //    = new AssemblyReferenceForm(_typeProvider);
            //form.ShowDialog();

            ////rebuild the toolbox with referenced assemblies
            //if (wfDesignCl.ToolboxControl != null)
            //{
            //    ((IToolboxService)wfDesignCl.ToolboxControl).Refresh();
            //}
        }

        private void menuItem2_Click(object sender, EventArgs e)
        {
            var frmProcDesgin = FrmProcDesgin.GetInstance();
            frmProcDesgin.Show();
        }

        //private WorkflowRuntime _workflowRuntime;
        //private AutoResetEvent _waitHandle = new AutoResetEvent(false);
        //private void menuItem启动_Click(object sender, EventArgs e)
        //{
        //    _workflowRuntime = new WorkflowRuntime();
        //    _workflowRuntime.WorkflowCompleted += delegate(object sender1, WorkflowCompletedEventArgs e1)
        //    {
        //        _waitHandle.Set();
        //    };
        //    _workflowRuntime.WorkflowTerminated += delegate(object sender2, WorkflowTerminatedEventArgs e2)
        //    {
        //        MessageBox.Show(String.Format("workflow terminated:{0}", e2.Exception.Message), "error in workflow");
        //        _waitHandle.Set();
        //    };
        //    Dictionary<String, Object> paras = new Dictionary<string, object>();
        //    paras.Add("Number", -6);
        //    #region Data from file
        //    //XmlReader reader = XmlReader.Create(@"顺序工作流.xoml");
        //    //XmlReader reader2 = XmlReader.Create(@"顺序工作流.rules");
        //    #endregion
        //    #region Data from sql
        //    string sql = "select wfmodule_id,wfmodule_name,wfdefinition,wfrule,wflayout from wfmodule where wfmodule_id=9";
        //    string[][] result = CommonLibrary.DB.DBExecuteUtil.querySqlArray(sql);
        //    TextReader str1 = new StringReader(result[0][2]);
        //    TextReader str2 = new StringReader(result[0][3]);
        //    XmlReader reader = XmlReader.Create(str1);
        //    XmlReader reader2 = XmlReader.Create(str2);
        //    #endregion
        //    WorkflowInstance instance = _workflowRuntime.CreateWorkflow(reader,reader2,null);
        //    instance.Start();
        //    MessageBox.Show("工作流启动完成");

        //}
    }
}
